const {
	innerWidth,
	innerHeight
} = window
const k = innerWidth / innerHeight
// 模型加载实例
const loader = new THREE.GLTFLoader()
const app = new Vue({
	el: "#app",
	mixins: [actionVisible, css3dRender],
	data: {
		// 场景实例
		scene: new THREE.Scene(),
		// 渲染场景实例
		renderer: new THREE.WebGLRenderer({
			antialias: true,
			alpha: true
		}),
		// 相机实例
		camera: new THREE.PerspectiveCamera(20, k, 1, 10000),
		// 辅助线实例
		axisHelper: new THREE.AxisHelper(100),
		// 拖拽控制器实例
		controls: null,
		// 是否开启拖拽
		isStartControls: false,
		// 底座对象
		planeObject: null,
		// 设备对象
		equipmentObject: null,
		// 扇叶整体对象
		untitledObject: null,
		// 选中设备
		selectEquipment: null,
		// 加载模型
		loadingModule: 0
	},
	mounted() {
		this.init()
		this.initCss3DScene()
		// 加载模型
		this.loadPlane()
		this.loadUntitled()
		this.loadEquipment()
		this.startAnimationFrame()
		this.initLight()
	},
	methods: {
		// 初始化基础场景配置
		init() {
			const {
				renderer,
				camera,
				scene,
				axisHelper
			} = this
			renderer.setSize(innerWidth, innerHeight)
			// 设置画布颜色和透明度
			renderer.setClearColor('#051d28', 1)
			// 将画布添加到指定容器内
			document.getElementById("app").appendChild(renderer.domElement)
			// 创建相机实例 PerspectiveCamera透视相机  用于3D场景
			camera.position.set(20, 20, 30)
			camera.lookAt(scene.position)
			// 添加辅助线
			// scene.add(axisHelper)
			// 添加拖拽,缩放
			this.initOrbitControls()
		},
		// 创建3D拖拽，缩放事件
		initOrbitControls() {
			const {
				camera,
				scene,
				renderer,
				cssRender
			} = this
			this.controls = new THREE.OrbitControls(camera, cssRender.domElement)
			// this.controls.maxDistance = 400
			this.controls.minDistance = 170
			this.controls.addEventListener('change', (event) => {
				this.isStartControls = true
				// cssRender.render(scene,camera)
			})
			this.controls.addEventListener('end', () => {
				setTimeout(() => {
					this.isStartControls = false
				}, 0)
			})
		},
		// 加载底座模型
		loadPlane() {
			this.planeObject = new THREE.GridHelper(800, 100, 0x007f7f, 0x007f7f)
			this.planeObject.position.set(0, -180, 0)
			this.scene.add(this.planeObject)
			this.loadingModule += 1
			// loader.load(`./glb/plane.glb`, object => {
			// 	this.planeObject = object
			// 	const {
			// 		scene
			// 	} = this.planeObject
			// 	const scale = 0.06
			// 	scene.scale.set(scale, scale, scale)
			// 	scene.position.set(0, -180, 0)
			// 	this.scene.add(scene)
			// 	this.renderer.render(this.scene, this.camera)
			// })
		},
		// 加载扇叶模型
		loadUntitled() {
			loader.load(`./glb/untitled.glb`, object => {
				this.untitledObject = object
				const untitledScene = object.scene
				const untitledScene_s = untitledScene.getObjectByName("扇叶_2")
				const {
					camera,
					scene,
					renderer
				} = this
				const scale = 0.02
				untitledScene.scale.set(scale, scale, scale)
				untitledScene.position.set(-0.2, -180.4, 0)
				// 去除实体
				untitledScene.getObjectByName("颜色材质").visible = false
				// 去除图灵水印
				untitledScene.getObjectByName('pCylinder205').visible = false
				scene.add(untitledScene)
				renderer.render(scene, camera)
				this.loadingModule += 1
			})
		},
		// 载入设备模型
		loadEquipment() {
			loader.load(`./glb/equipment.glb`, object => {
				const {
					camera,
					scene,
					renderer
				} = this
				this.equipmentObject = object
				const equipmentScene = object.scene
				const scale = 0.02
				this.initEquipmentBox()
				equipmentScene.children.forEach(child => {
					child.oldPosition = child.position.clone()
					child.material = child.material.clone()
					// child.material.lights = true
					child.material.wireframeLinewidth = 2
				})
				equipmentScene.scale.set(scale, scale, scale)
				equipmentScene.position.set(0, -180, 0)
				scene.add(equipmentScene)
				renderer.render(scene, camera)
				document.addEventListener("click", this.onPointerClick)
				this.loadingModule += 1
			})
		},
		// 初始化设备质心
		initEquipmentBox() {
			const polySurface152 = this.equipmentObject.scene.getObjectByName("polySurface152")
			polySurface152.geometry.computeBoundingBox()
			polySurface152.geometry.center()
			polySurface152.position.set(10, 9012, 460)
			polySurface152.rotation.z = 0
		},
		// 点击获取指定设备
		onPointerClick(event) {
			if (this.isStartControls) return
			const [w, h] = [innerWidth, innerHeight]
			const raycaster = new THREE.Raycaster()
			const mouse = new THREE.Vector3()
			mouse.x = (event.clientX / w) * 2 - 1
			mouse.y = -(event.clientY / h) * 2 + 1
			raycaster.setFromCamera(mouse, this.camera)
			const intersects = raycaster.intersectObject(this.equipmentObject.scene, true)
			if (intersects.length <= 0) return false
			this.selectEquipment = intersects[0].object
			this.animation(this.untitledObject.scene.rotation, {
				y: 0
			})
			this.animation(this.equipmentObject.scene.rotation, {
				y: 0
			})
			let {
				isMesh,
				isSelect,
				name
			} = this.selectEquipment
			this.equipmentObject.scene.children.forEach(material => {
				if (material.name === name && !isSelect && isMesh) {
					material.isSelect = true
					this.pointerSelect(material, name)
				} else if (material.isSelect) {
					material.isSelect = false
					this.removeSelect(material, name)
				}
			})
		},
		animation(oldData, newData, time = 1000, update, complete) {
			new TWEEN.Tween(oldData).to(newData, time)
				// .easing(TWEEN.Easing.Back.InOut)
				.onUpdate((object) => {
					update && update(object)
				})
				.onComplete(() => {
					complete && complete()
				})
				.start()
		},
		pointerSelect(material, name) {
			const {
				camera,
				scene,
				renderer,
				controls
			} = this
			material.material.emissive.setHex(0xf00000)
			controls.enabled = false
			const position = new THREE.Vector3().copy(camera.position)
			const newPosition = new THREE.Vector3(170, 0, 0)
			this.animation(
				position,
				newPosition,
				1000,
				() => {
					camera.position.copy(position)
					camera.lookAt(controls.target)
				},
				() => {
					this.load3DDom()
					controls.enabled = true
				}
			)
		},
		removeSelect(material, name) {
			material.material.emissive.setHex(0x000000)
		},
		// 执行侦动画
		startAnimationFrame() {
			const {
				camera,
				scene,
				renderer,
				cssRender,
				controls
			} = this
			requestAnimationFrame(this.startAnimationFrame)
			this.equipmentAnimation()
			this.untitledAnimation()
			renderer.render(scene, camera)
			controls.update()
			TWEEN.update()
		},
		// 设备动画
		equipmentAnimation() {
			const {
				overall,
				flabellum,
				overallSpeed,
				flabellumSpeed
			} = this.glb
			if (this.equipmentObject) {
				const {
					scene
				} = this.equipmentObject
				const polySurface152 = scene.getObjectByName("polySurface152")
				flabellum && (polySurface152.rotateZ(Number(flabellumSpeed)))
				overall && (scene.rotateY(-Number(overallSpeed)))
			}
		},
		// 整体风机动画
		untitledAnimation() {
			const {
				overall,
				flabellum,
				overallSpeed,
				flabellumSpeed
			} = this.glb
			if (this.untitledObject) {
				const {
					scene
				} = this.untitledObject
				const untitledScene_s = scene.getObjectByName("扇叶_2")
				flabellum && (untitledScene_s.rotateZ(Number(flabellumSpeed)))
				overall && (scene.rotateY(-Number(overallSpeed)))
			}
		},
		// 为当前场景添加光照
		loadLight([x, y, z]) {
			const spotLight = new THREE.DirectionalLight(0xffffff, 3)
			spotLight.position.set(x, y, z)
			this.scene.add(spotLight)
		},
		initLight() {
			const arr = [
				[1, 1, 1],
				[-1, 1, 1],
				[1, -1, 1],
				[1, 1, -1],
				[-1, -1, -1],
				[-1, -1, 1],
				[1, -1, -1],
				[-1, 1, -1]
			]
			arr.forEach(data => {
				this.loadLight(data)
				// this.addGeometry(data)
			})
		},
		// 模拟光源位置
		addGeometry([x, y, z]) {
			const geometry = new THREE.SphereGeometry(4, 4, 8)
			const material = new THREE.MeshLambertMaterial({
				color: 0xff0000
			})
			const mesh = new THREE.Mesh(geometry, material)
			mesh.position.set(x, y, z)
			scene.add(mesh)
		}
	}
})


// 模型内置动画
// const clock = new THREE.Clock()
// const mixer = new THREE.AnimationMixer(untitledScene)
// const clip = THREE.AnimationClip.findByName(
// 	object.animations,
// 	"Anim_0"
// )
// if (clip) {
// const action = mixer.clipAction(clip)
// action.play()
// }
// const render = () => {
// 	mixer.update(clock.getDelta())
// 	requestAnimationFrame(render)
// 	renderer.render(scene, camera)
// }
// render()
